home *** CD-ROM | disk | FTP | other *** search
/ Apple WWDC 1996 / WWDC96_1996 (CD).toast / Technology Materials / QuickTime VR / MacOS / QuickDraw™ 3D 1.0.6F4 SDK / Development / RAVE DDK 1.0.6 GM for MacOS / Projects / Test Code / TinselMipMap.c next >
Encoding:
C/C++ Source or Header  |  1996-04-30  |  6.2 KB  |  298 lines  |  [TEXT/MPCC]

  1. /******************************************************************************
  2.  **                                                                             **
  3.  **     Module:        TinselMipMap.c                                             **
  4.  **                                                                          **
  5.  **     Purpose:     Support file for mipmapping                              **
  6.  **                                                                          **
  7.  **     Author:        Mike W. Kelley                                             **
  8.  **                                                                             **
  9.  **                    2/3/95    Revised for 0.9 SDK release                         **
  10.  **                                                                          **
  11.  **     Copyright (C) 1994-95 Apple Computer, Inc.  All rights reserved.     **
  12.  **                                                                          **
  13.  *****************************************************************************/
  14.  
  15. #include <stdlib.h>
  16. #include <math.h>
  17. #include <string.h>
  18. #include <stdio.h>
  19.  
  20. /* Macintosh */
  21. #include <Types.h>
  22. #include <Resources.h>
  23. #include <QuickDraw.h>
  24. #include <Fonts.h>
  25. #include <Events.h>
  26. #include <Windows.h>
  27. #include <Menus.h>
  28. #include <TextEdit.h>
  29. #include <Dialogs.h>
  30. #include <Desk.h>
  31. #include <ToolUtils.h>
  32. #include <Memory.h>
  33. #include <SegLoad.h>
  34. #include <Files.h>
  35. #include <OSUtils.h>
  36. #include <OSEvents.h>
  37. #include <DiskInit.h>
  38. #include <Packages.h>
  39.  
  40. /* Project */
  41. #include "Drive3D.h"
  42. #include "TinselTest.h"
  43.  
  44. /*******************************************************************************************
  45.  *
  46.  * Create the mipmap for 'pixmap', and load it into 'texture'. Returns NULL on error.
  47.  *
  48.  ******************************************************************************************/
  49.  
  50. TQATexture *CreateMipMapTexture (
  51.     TQAEngine        *engine,
  52.     TexturePixel    *pixmap,
  53.     long            rowBytes,
  54.     long            widthNBits,
  55.     long            heightNBits)
  56. {
  57.     long            nImages;
  58.     long            width, height;
  59.     long            nPixels;
  60.     TexturePixel    *mipmap;
  61.     TQAImage        images [20];        /* Maximum conceivable number of TQAImages! */
  62.     long            i;
  63.     long            x, y;
  64.     long            oneHalf;
  65.     TQATexture        *texture;
  66.     TQAError        status;
  67.     
  68.     /*
  69.      * Allocate working space for the mip map images (starting with the
  70.      * 2^(widthNBits-1) x 2^(heightNBits-1) map), and for the array of
  71.      * TQAImages that describe the mip map and the parent map.
  72.      */
  73.     
  74.     nImages = ((widthNBits > heightNBits) ? widthNBits : heightNBits) + 1;
  75.     
  76.     width = 1 << (widthNBits - 1);        /* ??? Doesn't work for nBits == 0 */
  77.     height = 1 << (heightNBits - 1);    /* ??? Doesn't work for nBits == 0 */
  78.     
  79.     for (i = nImages - 1, nPixels = 0; i-- > 0; /* Nothing */)
  80.     {
  81.         nPixels += width * height;
  82.         
  83.         width >>= 1;
  84.         height >>= 1;
  85.         
  86.         if (width == 0)
  87.         {
  88.             width = 1;
  89.         }
  90.         if (height == 0)
  91.         {
  92.             height = 1;
  93.         }
  94.     }
  95.  
  96.     if ( ! (mipmap = malloc (sizeof (*pixmap) * nPixels)))
  97.     {
  98.         return (NULL);
  99.     }
  100.     
  101.     /*
  102.      * Fill in the TQAImage info.
  103.      */
  104.     
  105.     images[0].width = 1 << widthNBits;
  106.     images[0].height = 1 << heightNBits;
  107.     images[0].pixmap = pixmap;
  108.     images[0].rowBytes = rowBytes;
  109.     
  110.     width = 1 << (widthNBits - 1);        /* ??? Doesn't work for nBits == 0 */
  111.     height = 1 << (heightNBits - 1);    /* ??? Doesn't work for nBits == 0 */
  112.     
  113.     for (i = 1; i < nImages; ++i)
  114.     {
  115.         images[i].width = width;
  116.         images[i].height = height;
  117.         images[i].pixmap = mipmap;
  118.         images[i].rowBytes = width * sizeof (*mipmap);
  119.         
  120.         mipmap += width * height;
  121.         
  122.         width >>= 1;
  123.         height >>= 1;
  124.         
  125.         if (width == 0)
  126.         {
  127.             width = 1;
  128.         }
  129.         if (height == 0)
  130.         {
  131.             height = 1;
  132.         }
  133.     }
  134.  
  135.     /*
  136.      * oneHalf is used to round off the box filter of four pixels.
  137.      */
  138.     
  139.     oneHalf = 4 / 2;
  140.  
  141.     /*
  142.      * Create the mipmapped images.
  143.      */
  144.     
  145.     for (i = 1; i < nImages; ++i)
  146.     {
  147.         TQAImage            *prevImage, *image;
  148.         long            sourceRowBytes, targetRowBytes;
  149.         unsigned char    *sourceLine0, *sourceLine1;
  150.         unsigned char    *targetLine;
  151.         
  152.         prevImage = &images [i - 1];
  153.         image = &images [i];
  154.         
  155.         sourceLine0 = prevImage->pixmap;
  156.         
  157.         if (prevImage->height == 1)
  158.         {
  159.             /*
  160.              * Source image is height 1 (widthNBits must be greater than heightNBits).
  161.              * Make sourceLine1 duplicate sourceLine0, and set sourceRowBytes to 0 so we
  162.              * just keep re-reading the single source line.
  163.              */
  164.             
  165.             sourceRowBytes = 0;
  166.             sourceLine1 = sourceLine0;
  167.         }
  168.         else
  169.         {
  170.             /*
  171.              * Normal case. sourceLine1 points one scanline above sourceLine0.
  172.              */
  173.             
  174.             sourceRowBytes = prevImage->rowBytes;
  175.             sourceLine1 = sourceLine0 + sourceRowBytes;
  176.         }
  177.         
  178.         targetRowBytes = image->rowBytes;
  179.         targetLine = image->pixmap;
  180.  
  181.         for (y = image->height; y-- > 0; /* Nothing */)
  182.         {
  183.             unsigned char    *sourcePixel0, *sourcePixel1;
  184.             unsigned char    *targetPixel;
  185.             
  186.             sourcePixel0 = sourceLine0;
  187.             sourcePixel1 = sourceLine1;
  188.             targetPixel = targetLine;
  189.             
  190.             if (prevImage->width == 1)
  191.             {
  192.                 /*
  193.                  * Source image has width 1 (heightNBits must be greater than widthNBits).
  194.                  * Use a special inner loop that doesn't advance past the first pixel of
  195.                  * the source lines.
  196.                  */
  197.                 
  198.                 for (x = image->width; x-- > 0; /* Nothing */)
  199.                 {
  200.                     long    a, r, g, b;
  201.                     
  202.                     /*
  203.                      * Read and average two pixels from source into target.
  204.                      */
  205.                     
  206.                     a = sourcePixel0 [0] + (oneHalf >> 1);
  207.                     r = sourcePixel0 [1] + (oneHalf >> 1);
  208.                     g = sourcePixel0 [2] + (oneHalf >> 1);
  209.                     b = sourcePixel0 [3] + (oneHalf >> 1);
  210.                     
  211.                     a += sourcePixel1 [0];
  212.                     r += sourcePixel1 [1];
  213.                     g += sourcePixel1 [2];
  214.                     b += sourcePixel1 [3];
  215.                     
  216.                     *targetPixel++ = a >> 1;
  217.                     *targetPixel++ = r >> 1;
  218.                     *targetPixel++ = g >> 1;
  219.                     *targetPixel++ = b >> 1;
  220.                 }
  221.             }
  222.             else
  223.             {
  224.                 /*
  225.                  * Source image has at least width 2. This is the normal case.
  226.                  */
  227.                 
  228.                 for (x = image->width; x-- > 0; /* Nothing */)
  229.                 {
  230.                     long    a, r, g, b;
  231.                     
  232.                     /*
  233.                      * Read and average four pixels from source into target.
  234.                      */
  235.                     
  236.                     a = *sourcePixel0++ + oneHalf;
  237.                     r = *sourcePixel0++ + oneHalf;
  238.                     g = *sourcePixel0++ + oneHalf;
  239.                     b = *sourcePixel0++ + oneHalf;
  240.                     
  241.                     a += *sourcePixel1++;
  242.                     r += *sourcePixel1++;
  243.                     g += *sourcePixel1++;
  244.                     b += *sourcePixel1++;
  245.                     
  246.                     a += *sourcePixel0++;
  247.                     r += *sourcePixel0++;
  248.                     g += *sourcePixel0++;
  249.                     b += *sourcePixel0++;
  250.                     
  251.                     a += *sourcePixel1++;
  252.                     r += *sourcePixel1++;
  253.                     g += *sourcePixel1++;
  254.                     b += *sourcePixel1++;
  255.                     
  256.                     *targetPixel++ = a >> 2;
  257.                     *targetPixel++ = r >> 2;
  258.                     *targetPixel++ = g >> 2;
  259.                     *targetPixel++ = b >> 2;
  260.                 }
  261.             }
  262.             sourceLine0 += (sourceRowBytes << 1);
  263.             sourceLine1 += (sourceRowBytes << 1);
  264.             targetLine += targetRowBytes;
  265.         }
  266.     }
  267.     
  268.     status = QATextureNew (engine, kQATexture_Mipmap, kQAPixel_RGB32, images, &texture);
  269.     if (status != kQANoErr)
  270.     {
  271.         return (NULL);
  272.     }
  273.     
  274.     return (texture);
  275. }
  276.  
  277.  
  278.  
  279.  
  280.  
  281.  
  282.  
  283.  
  284.  
  285.  
  286.  
  287.  
  288.  
  289.  
  290.  
  291.  
  292.  
  293.  
  294.  
  295.  
  296.  
  297.  
  298.